<?php

namespace app\api\controller\wechat;

use app\common\controller\Api;
use fast\Http;
use fast\Random;
use app\common\model\User;
use app\common\library\Token;
use think\Config;
use think\Validate;
use app\common\exception\UploadException;
use app\common\library\Upload;
use app\common\library\Email;
use app\common\model\Ems;

/**
 * 小程序 用户
 */
class Users extends Api
{
    protected $noNeedLogin = ['login'];
    protected $noNeedRight = ['*'];

    // 
    // 
    
    protected $appid = 'wx2a3e79bac0c7c63d';
    protected $appsecret = '6b8d6a01b38367f53ed39017d7d83e52';

    protected $openId = null;
    protected $sessionKey = null;
    

    protected function getOpenID($code)
    {
        $datas = [
            "appid"=>$this->appid,
            "secret"=>$this->appsecret,
            "js_code"=>$code,
            "grant_type"=>"authorization_code"
        ];
        
        $url = 'https://api.weixin.qq.com/sns/jscode2session';


        $result = Http::get($url,$datas);

        if(is_string($result)){
            $result = json_decode($result,true);
        }

        $this->openId = $result["openid"] ?? null;
        
        $this->sessionKey = $result["session_key"] ?? null;
    }

    /**
     * 登录
     *
     */
    public function login()
    {
        $code = input('code','');
        if(empty($code) || strlen($code) !== 32){
            $this->error('code参数不符合要求');
        }

        $this->getOpenID($code);

        if(is_null($this->openId)){
            $this->error('获取openId失败');
        }

        // 查询用户是否存在
        $user = User::where('openid',$this->openId)->find();
        $this->auth->setAllowFields(['id', 'number']);
        if($user){
            // 提高安全性
            Token::clear($user["id"]);
            // 登录
            $this->auth->direct($user["id"]);
            $userinfo = $this->auth->getUserinfo();
        }
        else{

            // 注册
            $username = substr($this->openId,-6).date('hms');
            $password = Random::alnum(16);
            $this->auth->register($username,$password,'','',[
                "openid"=>$this->openId
            ]);
            // 日期时间 id
            $userinfo = $this->auth->getUserinfo();
            $userid = $userinfo["id"];
            $number = date('ymdHis'). $userid;
            User::where('id',$userid)->update([
                "number"=>$number
            ]);

            $userinfo["number"] = $number;
        }
        
        $this->success('登录成功',$userinfo);
    }

    /**
     * 获取用户信息
     *
     * @return void
     */
    public function getUserinfo()
    {
        $this->auth->setAllowFields(['id', 'number','name','gender','avatar','email','auth']);
      
        $userinfo = $this->auth->getUserinfo();
        $userinfo["gender"] = is_null($userinfo["gender"])?null: ($userinfo["gender"] === 1?'男':'女');
        $userinfo["shownamegender"] = Config::get('site.shownamegender');
        $this->success('',$userinfo);
    }

    /**
     * 设置用户信息
     *
     * @return void
     */
    public function setUserinfo()
    {
        $params = input('post.');

        $rules = [
            'name'=>'require|length:2,10',
            'gender'=>'require|in:0,1'
        ];     
        
        $msg = [
            'name.require' => '姓名不能为空',
            'name.length' => '姓名长度必须在2-10个字符之间',
            'gender.require' => '性别不能为空',
            'gender.in' => '性别必须是0或1'
        ];

        $validate = new Validate($rules,$msg);
        if(!$validate->check($params)){
            $this->error($validate->getError());
        }

        $saveData = [
            "name"=>$params["name"],
            "gender"=>$params["gender"],
        ];

        $res = User::where('id',$this->auth->id)->update($saveData);

        if($res){
            $this->success('更新成功');
        }
        else{
            $this->error('更新失败');
        }
    }

    /**
     * 设置用户头像
     *
     * @return void
     */
    public function setAvatar()
    {
        Config::set('default_return_type', 'json');
        //必须设定cdnurl为空,否则cdnurl函数计算错误
        Config::set('upload.cdnurl', '');

        $attachment = null;
        //默认普通上传文件
        $file = $this->request->file('file');
        try {
            $upload = new Upload($file);
            $attachment = $upload->upload("/uploads/user/".$this->auth->id.'/');
        } catch (UploadException $e) {
            $this->error($e->getMessage());
        }

        $res = User::where('id',$this->auth->id)->update([
            "avatar"=>$attachment->url
        ]);

        if($res){
            $this->success('上传成功',cdnurl($attachment->url, true));
        }
        else{
            $this->error('上传失败');
        }

        // $this->success(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
    }
   
    public function setemail()
    {
        if($this->request->isPost())
        {
            $email = $this->request->param('email', '', 'trim');
            $code = $this->request->param('code', '', 'trim');

            $Businessinfo = User::where('id',$this->auth->id)->find();

            if (!$Businessinfo)
            {
                $this->error('用户不存在');
                exit;
            }

            if ($email == $Businessinfo['email'] && $Businessinfo['auth'] == '1')
            {
                $this->error('邮箱已认证，无需重复认证');
                exit;
            }

            $emailinfo = Ems::where(['email' => $email, 'code' => $code])->find();

            if(!$emailinfo)
            {
                $this->error('验证码错误,请重新输入');
                exit;
            }

            Ems::startTrans();
            User::startTrans();

            $BusinessStatus = User::where('id',$this->auth->id)->update([
                'email' => $email,
                'auth' => '1'
            ]);
            
            
            if($BusinessStatus === false)
            {
                $this->error($this->BusinessModel->getError());
                exit;
            }

            $EmsStatus = Ems::destroy($emailinfo['id']);

            if($EmsStatus === false)
            {
                User::rollback();
                $this->error(Ems::getError());
                exit;
            }

            if($BusinessStatus === false || $EmsStatus === false)
            {
                User::rollback();
                Ems::rollback();
                $this->error('邮箱认证失败');
                exit;
            }
            else
            {
                User::commit();
                Ems::commit();
                $this->success('邮箱认证成功');
                exit;
            }
        }
    }

    public function sendemail()
    {   
        $busid = $this->request->param('busid', 0, 'trim');
        $email = $this->request->param('email', '', 'trim');

        $Businessinfo = User::where('id',$busid)->find();
        if (!$Businessinfo)
        {
            $this->error('用户不存在');
            exit;
        }
        
        $emailinfo = Ems::field('createtime')->where(['email' => $email])->find();
        $emailcreatetime = $emailinfo['createtime'] ?? 0;

        if(strtotime($emailcreatetime) + 60 >= time())
        {
            $this->error('验证已发送，请去邮箱查询');
            exit;
        }else{
            $emaildel = Ems::where(['email' => $email])->delete();
            if($emaildel === false){
                $this->error(Ems::getError());
                exit;
            }
        }

        // 验证码
        $code = build_randstr(4);

        $content = "<h1>医考练习平台邮箱验证码:  $code,如果不是您发送的验证码，请忽略。</h1>";

        // 实例化一个Email对象
        $emailobj = new Email;

        // 开启事务
        Ems::startTrans();

        $EmsData = [
            'event' => '医考练习平台邮箱认证',
            'email' => $email,
            'code' =>  $code
        ];
        $emsInstance = new Ems();
        $EmsStatus = $emsInstance->validate('Ems')->save($EmsData);

        if($EmsStatus === false)
        {
            $this->error(Ems::getError());
            exit;
        }

        // 发送邮件
        $emailstatus = $emailobj->subject('医考练习平台邮箱认证')->to($email)->message($content)->send();

        if($emailstatus === false)
        {
            Ems::rollback();
            $this->error($emailobj->getError());
            exit;
        }
        

        if($emailstatus === false || $EmsStatus === false)
        {
            Ems::rollback();
            $this->error('发送失败');
            exit;
        }
        else
        {
            Ems::commit();
            $this->success('发送成功');
            exit;
        }
    }
}
